package com.fingard.dsp.bank.directbank.spdb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IBalanceCheckConfirm;
import com.fingard.dsp.bank.directbank.spdb01.authforrec.StringUtils;
import com.fingard.dsp.bank.reqrespobj.balancecheck.RetAtsBalCheckQry;
import com.fingard.dsp.bank.reqrespobj.balancecheck.detail.RetAtsBalCheckDetail;
import com.fingard.dsp.bank.reqrespobj.balancecheckconfirm.ReqBalCheckConfirmQry;
import com.fingard.dsp.bank.reqrespobj.balancecheckconfirm.RetAtsBalCheckConfirmQry;
import com.fingard.dsp.bank.reqrespobj.balancecheckconfirm.detail.ReqBalCheckConfirmDetail;
import com.fingard.dsp.bank.reqrespobj.balancecheckconfirm.detail.RetAtsBalCheckConfirmDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;


import java.text.Normalizer;
import java.util.Date;

public class SPDB01BalanceCheckConfirm extends SPDB01Base implements IBalanceCheckConfirm {
    /**
     * 设想方案：余额对账查询7058将所有签约账号下的对账单查询回来，余额对账确认将批量确认，满足ER43的设计
     * @param p_req7509
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsBalCheckConfirmQry d_7509_BalCheckConfirm(ReqBalCheckConfirmQry p_req7509) throws Exception {
        //余额对账确认返回ATS的对象
        RetAtsBalCheckConfirmQry retAts = new RetAtsBalCheckConfirmQry(p_req7509.reqHeader);
        //写返回ATS的统一头部信息
        retAts.writeStart();

        try {
            SPDB01Header er43BnkHeader = new SPDB01Header();
            er43BnkHeader.transCode = "ER43";
            XmlTextWriter er43Writer = new XmlTextWriter();
            //银行报文通用头部
            ReqBalCheckConfirmDetail readedDetail;
            String checkDate = "";//发送的账期
            String tmpCheckDate = "";//每一个账号的账期
            boolean isSame = true;//判断子账号是否相符
            int notSameCount = 0;//不相符的账号个数

            er43Writer.writeStartElement("body");
            er43Writer.writeElementString("acctNo", getBankConfig().getValueAsString("mainAcctNo"));//主账号从配置文件中拿取
            er43Writer.writeElementString("checkDate", checkDate);//账期 yyyyMMDD 由fw47和fp99中返回的。该账期在dsp请求报文中必须全部一致
            er43Writer.writeElementString("isSame", "1");//1:相符 0：不相符 若输入相符：则该主账号下，该账期所有的子账号的状态为对账相符。             若送不相符：除了输入明细中不相符的子账号，剩余子账户均为相符
            er43Writer.writeStartElement("lists");
            while (p_req7509.readRecord()) {
                readedDetail =p_req7509.readedDetail;
                checkDate = FW47_deal(readedDetail.actNum, readedDetail.statementNumber, readedDetail.yearMonth);
                /**
                 * 判断每个账号是否余额相符
                 */
                if (!"2".equals(readedDetail.dzFlag)) {// 对账结果 2平（余额相符），3不平（余额不符），1未对账，7调节相符
                    er43Writer.writeStartElement("list");
                    er43Writer.writeElementString("subAcctNo", readedDetail.actNum);//不符的账号
                    er43Writer.writeElementString("amout", readedDetail.custActBal);//客户余额
                    er43Writer.writeElementString("reasons", readedDetail.notConfirmReason);//不符原因
                    er43Writer.writeEndElement();
                    notSameCount++;
                }
            }
            er43Writer.insertIntoTag("checkDate", checkDate);//修改对账日期
            if (notSameCount > 0)
                er43Writer.insertIntoTag("isSame", "0");//修改是否相符
            er43Writer.writeEndDocument();

            String[] tmpRetBkStr = sendToBank(er43Writer.toXmlString(), er43BnkHeader);
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                    String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                    if ("AAAAAAA".equals(returnCode)) {
                        RetAtsBalCheckConfirmDetail tmpRetDetail = new RetAtsBalCheckConfirmDetail();
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.respInfo = returnMsg;
                        tmpRetDetail.actNum = getBankConfig().getValueAsString("mainAcctNo");//主账号
                        String result = tmpBkReader.readedXElement.getSingleTextNotNull("isSame");//返回给结果，1：相符 0：不相符
                        if ("1".equals(result)) {
                            tmpRetDetail.dzFlag = "2";//相符
                        } else {
                            tmpRetDetail.dzFlag = "3";//不相符
                        }
                        int dealStatus = Integer.parseInt(tmpBkReader.readedXElement.getSingleTextNotNull("dealStatus"));
                        if (dealStatus > 0) {
                            tmpRetDetail.result = "2";
                        } else {
                            tmpRetDetail.result = "3";//todo 文档中除了成功与失败暂无其他处理状态，需要另外咨询银行
                        }
                        retAts.writeRetDetail(tmpRetDetail, p_req7509.isBatch);

                    } else {
                        retAts = new RetAtsBalCheckConfirmQry(p_req7509.reqHeader);
                        retAts.writeStart();//写返回ATS的统一头部信息
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo(returnMsg);
                    }
                } else {
                    retAts = new RetAtsBalCheckConfirmQry(p_req7509.reqHeader);
                    retAts.writeStart();//写返回ATS的统一头部信息
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpSbMsg.toString());
                }
            } else {
                retAts = new RetAtsBalCheckConfirmQry(p_req7509.reqHeader);
                retAts.writeStart();//写返回ATS的统一头部信息
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(tmpRetBkStr[1]);
            }
        } catch (Exception ex) {
            retAts = new RetAtsBalCheckConfirmQry(p_req7509.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(ex.getMessage());
        }
        retAts.writeEnd();
        return retAts;
    }

    public String FW47_deal(String actNum, String statementNumber, String yearMonth) throws Exception {
        String checkDate = "";
        try {
            /**
             * （1）dsp 报文无确定的账单编号字段，先用FW47进行模糊查询
             */
            SPDB01Header tmpBnkHeader = new SPDB01Header();
            tmpBnkHeader.transCode = "FW47";
            XmlTextWriter fw47Writer = new XmlTextWriter();
            //报文主体
            fw47Writer.writeStartElement("body");
            fw47Writer.writeElementString("checkNo", statementNumber);//账单编号 非必填
            fw47Writer.writeElementString("transMasterID", bankFront.org);//交易客户号
            fw47Writer.writeElementString("acctNo", actNum);//账号  已签约为MD51为主账号  未签约可以填客户下的任一账号
            fw47Writer.writeElementString("checkType", "");//账单类型代码 0-纸质，1-电子 为空时默认电子账单
            fw47Writer.writeElementString("checkStatus", "");//账单状态  0-可不对账;1-未对账;2-已对账;
            Date DateFrom = Format.Date6Format.parse(yearMonth);
            fw47Writer.writeElementString("beginDate", Format.Date8Format.format(formatFirstOfMonth(DateFrom)));//开始日期 YYYYMMDD  当月的第一天
            fw47Writer.writeElementString("endDate", Format.Date8Format.format(formatEndOfMonth(DateFrom)));    //结束日期 YYYYMMDD  当月的最后一天  开始日期和截止日期不超过一年
            fw47Writer.writeElementString("beginNumber", "1");//起始笔数
            fw47Writer.writeElementString("queryNumber", "50");//查询笔数  最大50 超过默认50
            fw47Writer.writeEndDocument();
            //发送至银行接口
            String[] tmpRetBkStr = sendToBank(fw47Writer.toXmlString(), tmpBnkHeader);

            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                    String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                    if ("AAAAAAA".equals(returnCode)) {
                        while (tmpBkReader.read("/packet/body/list")) {
                            //每一个账单新建一个detail对象，用于存储每一笔账单的详细信息
                            RetAtsBalCheckDetail p_retDetail = new RetAtsBalCheckDetail();
                            XElement fw47info = tmpBkReader.readedXElement;
                            checkDate = fw47info.getSingleTextNotNull("checkDate");//账单日期
                            break;//找到第一笔
                        }
                    } else {
                        throw new Exception(returnMsg);
                    }
                } else {
                    throw new Exception(tmpSbMsg.toString());
                }
            } else {
                throw new Exception(tmpRetBkStr[1]);
            }
        } catch (Exception ex) {
            throw ex;
        }
        if (StringHelper.isNullOrEmpty(checkDate)) {
            throw new Exception("未在FW47里找到账单日期");
        } else {
            return checkDate;
        }
    }
}
